from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from stall import models
from user.models import User


class StallShowSerializer(serializers.Serializer):
    stall_id = serializers.IntegerField(source='id', read_only=True)
    user_id = serializers.IntegerField(read_only=True)
    board_url = serializers.CharField(read_only=True)
    name = serializers.CharField(read_only=True)
    style = serializers.CharField(read_only=True)
    s_style = serializers.CharField(read_only=True)
    region_id = serializers.IntegerField(read_only=True)
    zone_id = serializers.IntegerField(read_only=True)
    order_id = serializers.IntegerField(read_only=True)
    state = serializers.CharField(read_only=True)
    quarter_sales = serializers.IntegerField(read_only=True)
    month_sales = serializers.IntegerField(read_only=True)
    week_sales = serializers.IntegerField(read_only=True)
    food_sort = serializers.CharField(read_only=True)
    food_sort_list = serializers.SerializerMethodField()
    part_sort = serializers.CharField(read_only=True)
    part_sort_list = serializers.SerializerMethodField()

    def get_food_sort_list(self, instance):
        return instance.food_sort.split('$')

    def get_part_sort_list(self, instance):
        return instance.part_sort.split('$')


class ZoneShowSerializer(serializers.Serializer):
    name = serializers.CharField(read_only=True)
    region_id = serializers.IntegerField(read_only=True)
    zone_id = serializers.IntegerField(read_only=True)
    num = serializers.CharField(read_only=True)
    bottom = serializers.CharField(read_only=True)
    left = serializers.CharField(read_only=True)
    sales = serializers.SerializerMethodField()

    def get_sales(self, instance):
        stall_list = models.Stall.objects.filter(num__startswith=instance.num)
        if stall_list:
            sales = {
                'quarter_sales': 0,
                'month_sales': 0,
                'week_sales': 0,
            }
            for stall in stall_list:
                stall_sales = stall.sales.split('$')
                sales['quarter_sales'] += int(stall_sales[0])
                sales['month_sales'] += int(stall_sales[1])
                sales['week_sales'] += int(stall_sales[2])
            return sales
        else:
            return None


class GetRegionSerializer(serializers.Serializer):
    name = serializers.CharField(read_only=True)
    region_id = serializers.CharField(read_only=True)
    map_url = serializers.CharField(read_only=True)


class FoodShowSerializer(serializers.Serializer):
    food_id = serializers.IntegerField(source='id', read_only=True)
    stall_id = serializers.CharField(read_only=True)
    plate_url = serializers.CharField(read_only=True)
    sort = serializers.CharField(read_only=True)
    name = serializers.CharField(read_only=True)
    price = serializers.DecimalField(read_only=True, max_digits=6, decimal_places=2)
    desc = serializers.CharField(read_only=True)
    month_sales = serializers.IntegerField(read_only=True)


class PartShowSerializer(serializers.Serializer):
    stall_id = serializers.CharField(read_only=True)
    sort = serializers.CharField(read_only=True)
    name = serializers.CharField(read_only=True)
    price = serializers.DecimalField(read_only=True, max_digits=6, decimal_places=2)
    part_url = serializers.CharField(read_only=True)
    desc = serializers.CharField(read_only=True)
    order = serializers.IntegerField(read_only=True)


class StallNumChoseSerializer(serializers.Serializer):
    region_id = serializers.CharField(read_only=True)
    zone_id = serializers.CharField(read_only=True)
    order_id = serializers.CharField(read_only=True)


class CreateStallSerializer(serializers.Serializer):
    user_id = serializers.CharField(write_only=True)
    stall_name = serializers.CharField(write_only=True)
    region_id = serializers.CharField(write_only=True)
    zone_id = serializers.CharField(write_only=True)
    order_id = serializers.CharField(write_only=True)
    food_sort = serializers.CharField(write_only=True)
    part_sort = serializers.CharField(write_only=True)
    stall_style = serializers.IntegerField(write_only=True)
    stall_s_style = serializers.IntegerField(write_only=True)

    def validate(self, attrs):
        stall_name = attrs.get('stall_name')
        food_sort = attrs.get('food_sort')
        part_sort = attrs.get('part_sort')
        if len(stall_name) > 12:
            raise ValidationError('摊位名称不得超过12位')
        if '$' not in food_sort:
            raise ValidationError('至少设置两个小吃分类')
        if '$' not in part_sort:
            raise ValidationError('至少设置两个配件分类')
        stall = models.Stall.objects.filter(name=stall_name)
        if stall:
            raise ValidationError('摊位名称已存在')
        return attrs

    def create(self, validated_data):
        user_id = validated_data.get('user_id')
        stall_name = validated_data.get('stall_name')
        region_id = validated_data.get('region_id')
        zone_id = validated_data.get('zone_id')
        order_id = validated_data.get('order_id')
        stall_num = region_id + '$' + zone_id + '$' + order_id
        food_sort = validated_data.get('food_sort')
        part_sort = validated_data.get('part_sort')
        stall_style = validated_data.get('stall_style')
        stall_s_style = validated_data.get('stall_s_style')
        instance = models.Stall.objects.create(
            name=stall_name,
            style=stall_style,
            s_style=stall_s_style,
            num=stall_num,
            user_id=user_id,
            food_sort=food_sort,
            part_sort=part_sort,
        )
        new_user_info = '1$2$' + str(instance.id)
        user = User.objects.filter(id=user_id).first()
        user.user_info = new_user_info
        user.save()
        return instance


class RegionShowSerializer(serializers.Serializer):
    region_id = serializers.CharField(read_only=True)
    name = serializers.CharField(read_only=True)
    sales = serializers.SerializerMethodField()

    def get_sales(self, instance):
        stall_list = models.Stall.objects.filter(num__startswith=instance.region_id)
        if stall_list:
            sales = {
                'quarter_sales': 0,
                'month_sales': 0,
                'week_sales': 0,
            }
            for stall in stall_list:
                stall_sales = stall.sales.split('$')
                sales['quarter_sales'] += int(stall_sales[0])
                sales['month_sales'] += int(stall_sales[1])
                sales['week_sales'] += int(stall_sales[2])
            return sales
        else:
            return None


class GetStallSerializer(serializers.Serializer):
    stall_id = serializers.IntegerField(source='id', read_only=True)
    user_id = serializers.IntegerField(read_only=True)
    board_url = serializers.CharField(read_only=True)
    stall_name = serializers.CharField(source='name', read_only=True)
    style = serializers.IntegerField(read_only=True)
    s_style = serializers.IntegerField(read_only=True)
    quarter_sales = serializers.IntegerField(read_only=True)
    month_sales = serializers.IntegerField(read_only=True)
    week_sales = serializers.IntegerField(read_only=True)
    state = serializers.IntegerField(read_only=True)
    num = serializers.CharField(read_only=True)
    food_sort_list = serializers.SerializerMethodField()
    part_sort_list = serializers.SerializerMethodField()
    place = serializers.SerializerMethodField()

    def get_food_sort_list(self, instance):
        return instance.food_sort.split('$')

    def get_part_sort_list(self, instance):
        return instance.part_sort.split('$')

    def get_place(self, instance):
        place_num_list = instance.num.split('$')
        zone_num = place_num_list[0] + '$' + place_num_list[1]
        region = models.Region.objects.filter(region_id=place_num_list[0]).first()
        region_name = region.name
        zone = models.Zone.objects.filter(num=zone_num).first()
        zone_name = zone.name
        return '{}--{}--{}号摊位'.format(region_name, zone_name, place_num_list[2])


class CreateFoodSerializer(serializers.Serializer):
    stall_id = serializers.IntegerField(write_only=True)
    sort = serializers.CharField(write_only=True)
    name = serializers.CharField(write_only=True)
    price = serializers.CharField(write_only=True)
    desc = serializers.CharField(write_only=True)

    def validate(self, attrs):
        stall_id = attrs.get('stall_id')
        sort = attrs.get('sort')
        name = attrs.get('name')
        price = attrs.get('price')
        desc = attrs.get('desc')
        try:
            if '.' in price:
                price = float(price)
            else:
                price = int(price)
        except Exception as e:
            raise ValidationError('价格必须为数字')
        models.Food.objects.create(
            stall_id=stall_id,
            sort=sort,
            name=name,
            price=price,
            desc=desc
        )
        return attrs


class UpdateFoodSerializer(serializers.Serializer):
    food_id = serializers.IntegerField(write_only=True)
    name = serializers.CharField(write_only=True)
    price = serializers.CharField(write_only=True)
    desc = serializers.CharField(write_only=True)

    def validate(self, attrs):
        food_id = attrs.get('food_id')
        name = attrs.get('name')
        price = attrs.get('price')
        desc = attrs.get('desc')
        try:
            if '.' in price:
                price = float(price)
            else:
                price = int(price)
        except Exception as e:
            raise ValidationError('价格必须为数字')
        models.Food.objects.filter(id=food_id).update(
            name=name,
            price=price,
            desc=desc
        )
        return attrs


class GetBillSerializer(serializers.Serializer):
    bill_id = serializers.IntegerField(source='id', read_only=True)
    bill_num = serializers.CharField(read_only=True)
    stall_id = serializers.IntegerField(read_only=True)
    user_id = serializers.IntegerField(read_only=True)
    bill_price = serializers.SerializerMethodField()
    row_list = serializers.SerializerMethodField()

    def get_row_list(self, instance):
        row_list = []
        bill_id = instance.id
        row_food_set = models.Row.objects.filter(bill_id=bill_id, part_id=0)
        row_part_set = models.Row.objects.filter(bill_id=bill_id, food_id=0)
        for row in row_food_set:
            food = models.Food.objects.filter(id=row.food_id).first()
            data = {
                'name': food.name,
                'price': food.price,
                'img_url': food.plate_url,
                'count': row.count
            }
            row_list.append(data)
        for row in row_part_set:
            part = models.Part.objects.filter(id=row.part_id).first()
            data = {
                'name': part.name,
                'price': part.price,
                'img_url': part.part_url,
                'count': row.count
            }
            row_list.append(data)
        return row_list

    def get_bill_price(self, instance):
        bill_list = self.get_row_list(instance)
        bill_price = 0
        for row in bill_list:
            bill_price += row.get('price') * row.get('count')
        bill_price = '%.2f' % bill_price
        return bill_price
